package ewan.android.droidjockey;

import android.content.ContentProvider;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.text.TextUtils;
import java.util.Arrays;
import java.util.HashSet;

public class SongInfoStoreContentProvider extends ContentProvider {

	//Database
	private SongInfoStoreHelper database;
	
	//Used for the UriMatcher
	private static final int SONGS = 10;
	private static final int SONG_ID = 20;
	
	private static final String AUTHORITY = "ewan.android.droidjockey.contentprovider";
	
	private static final String BASE_PATH = "songs";
	public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/" + BASE_PATH);
	
	public static final String CONTENT_TYPE = ContentResolver.CURSOR_DIR_BASE_TYPE + "/songs";
	public static final String CONTENT_ITEM_TYPE = ContentResolver.CURSOR_ITEM_BASE_TYPE + "/song";
	
	private static final UriMatcher sURIMatcher = new UriMatcher(UriMatcher.NO_MATCH);
	
	static {
		sURIMatcher.addURI(AUTHORITY, BASE_PATH, SONGS);
		sURIMatcher.addURI(AUTHORITY, BASE_PATH + "/#", SONG_ID);
	}
	@Override
	public boolean onCreate(){
		database = new SongInfoStoreHelper(getContext());
		return false;
	}
	
	@Override
	public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
		SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
		
		checkColumns(projection);
 		
		queryBuilder.setTables(SongInfoStore.TABLE_NAME);
		
		int uriType = sURIMatcher.match(uri);
		switch (uriType){
		case SONGS:
			break;
		case SONG_ID:
			//Adding the ID to the original query
			queryBuilder.appendWhere(SongInfoStore.COLUMN_ID + "=" + uri.getLastPathSegment());
			break;
		default:
			throw new IllegalArgumentException("Unknown URI: " + uri);
		}
		
		SQLiteDatabase db = database.getWritableDatabase();
		Cursor cursor = queryBuilder.query(db, projection, selection, selectionArgs, null, null, sortOrder);
		//Make sure that potential listeners are notified
		cursor.setNotificationUri(getContext().getContentResolver(), uri);
		
		return cursor;
	}
	
	@Override
	public String getType(Uri uri) {
		return null;
	}

	@Override
	public Uri insert(Uri uri, ContentValues values) {
		int uriType = sURIMatcher.match(uri);
		SQLiteDatabase sqlDB = database.getWritableDatabase();
		long id = 0;
		switch (uriType) {
		case SONGS:
			id = sqlDB.insert(SongInfoStore.TABLE_NAME, null, values);
			break;
		default:
			throw new IllegalArgumentException("Unknown URI: " + uri);
			}
		getContext().getContentResolver().notifyChange(uri, null);
		return Uri.parse(BASE_PATH + "/" + id);
	}
	@Override
	public int delete(Uri uri, String selection, String[] selectionArgs){
		int uriType = sURIMatcher.match(uri);
		SQLiteDatabase sqlDB = database.getWritableDatabase();
		int rowsDeleted = 0;
		switch (uriType) {
		case SONGS:
			rowsDeleted = sqlDB.delete(SongInfoStore.TABLE_NAME, selection, selectionArgs);
			break;
		case SONG_ID:
			String id = uri.getLastPathSegment();
			if (TextUtils.isEmpty(selection)) {
				rowsDeleted = sqlDB.delete(
								SongInfoStore.TABLE_NAME,
								SongInfoStore.COLUMN_ID + "=" + id,
								null);
			} else {
					rowsDeleted = sqlDB.delete(SongInfoStore.TABLE_NAME,
												SongInfoStore.COLUMN_ID + "=" + id
												+ " and " + selection,
												selectionArgs);
				}
			break;
		default:
				throw new IllegalArgumentException("Unknown URI: " + uri);
			}
		getContext().getContentResolver().notifyChange(uri, null);
		return rowsDeleted;
		}
	
	@Override
	public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
		
		int uriType = sURIMatcher.match(uri);
		SQLiteDatabase sqlDB = database.getWritableDatabase();
		int rowsUpdated = 0;
		switch (uriType) {
		case SONGS:
			rowsUpdated = sqlDB.update(SongInfoStore.TABLE_NAME, values, selection, selectionArgs);
			break;
		case SONG_ID:
			String id = uri.getLastPathSegment();
		if (TextUtils.isEmpty(selection)){
			rowsUpdated = sqlDB.update(SongInfoStore.TABLE_NAME, values, SongInfoStore.COLUMN_ID + "=" + id, null);
		}else {
			rowsUpdated = sqlDB.update(SongInfoStore.TABLE_NAME, values, SongInfoStore.COLUMN_ID + "=" + id + " and " + selection, selectionArgs);
		}
		break;
	default:
		throw new IllegalArgumentException("Unknown URI: " + uri);
		}
		getContext().getContentResolver().notifyChange(uri, null);
		return rowsUpdated;
	}
	
	private void checkColumns(String[] projection) {
		String[] available = {  SongInfoStore.COLUMN_ID,
								SongInfoStore.COLUMN_TITLE,
								SongInfoStore.COLUMN_ARTIST,
								//SongInfoStore.COLUMN_ALBUM,
								SongInfoStore.COLUMN_DANCE,
								SongInfoStore.COLUMN_LOUD,
								SongInfoStore.COLUMN_MODE,
								SongInfoStore.COLUMN_ENERGY,
								SongInfoStore.COLUMN_LENGTH,
								SongInfoStore.COLUMN_TEMPO,
								SongInfoStore.COLUMN_TIMESIG,
								SongInfoStore.COLUMN_TERMS };
		if (projection != null) {
			HashSet<String> requestedColumns = new HashSet<String>(Arrays.asList(projection));
			HashSet<String> availableColumns = new HashSet<String>(Arrays.asList(available));
		
			if (!availableColumns.containsAll(requestedColumns)) {
				throw new IllegalArgumentException("Unknown columns in projection");
			}
		}
	}
}